<?php
/**
 *缺货需求(A需求)模型
 *@author shipanpan
 */
class Cron_Model_Backup_StockoutStory extends Application_Model_StockoutStory {
	private $_productGradeModel;
	private $_storyBackupLogModel;
	private $_storyModel;

	public function __construct() {
		$this->db = $this->db();
	}

	/**
	 * 生成备货需求
	 * @return bool
	 */
	public function create() {
		$stockoutProductModel = new Cron_Model_Backup_Stockout();
		$stockoutProductAmount = $stockoutProductModel->getAllAmount();
		$storyModel = new Cron_Model_Backup_Story();

		if (!$stockoutProductAmount) {
			return $this->_error("缺货商品数为零！");
		}

		//缺货商品可能很多，采取分批查询
		$pageSize = 1000;
		$count = ceil($stockoutProductAmount / $pageSize);

		for ($i = 0; $i <= $count; $i++) {
			$offset = $pageSize * $i;
			$waitingGoodsList = $this->_getWaitingGoodsList($offset, $pageSize);
			if (empty($waitingGoodsList)) {
				continue;
			}
			foreach ($waitingGoodsList as $waitingGoods) {
				$this->_storyBackupLogModel = new Cron_Model_Backup_Log($waitingGoods['goods_sn'], $waitingGoods['backup_warehouse']);

				$isConformStandard = $this->_isConformStandard($waitingGoods);
				if ($isConformStandard) {
					if (!$this->_interceptCheck($waitingGoods)) {
						$createInterceptStroyResult = $storyModel->createInterceptStory($waitingGoods['goods_sn'], $waitingGoods['backup_warehouse'], 'a', $waitingGoods['quantity'], 1);
					} else {
						$createStroyResult = $storyModel->create($waitingGoods['goods_sn'], $waitingGoods['backup_warehouse'], 'a', $waitingGoods['quantity']);
					}
					$this->_storyBackupLogModel->log('a_story_quantity', $waitingGoods['quantity']);
				}
				$this->_storyBackupLogModel->write();
			}

		}

	}

	/**
	 * 检查产品是否符合缺货需求
	 * @param  array        $stockOutGoods            缺货产品数组，数组需包含['']
	 * @param  bool|boolean $oneFailImmediatelyReturn 是否只要有一个检查项不通过就立即停止检查且返回false
	 * @return 符合缺货需求返回true，不符合返回false
	 */
	private function _isConformStandard(array $stockOutGoods, bool $oneFailImmediatelyReturn = false) {
		$needCheckItem = ['stockoutQuantity', 'productGrade', 'productCatalog', 'productResourceStatus', 'productIsClearance'];
		$isConform = true;
		$this->_storyBackupLogModel->log('has_calculate_a_story', 1);
		$this->_storyBackupLogModel->log('stock', $stockOutGoods['stock']);
		$this->_storyBackupLogModel->log('the_90_days_order', $stockOutGoods['order_occupy_quarter']);
		foreach ($needCheckItem as $checkItem) {
			$itemCheckMethod = "_" . $checkItem . "Check";
			$checkResult = $this->$itemCheckMethod($stockOutGoods);
			if ($checkResult === false) {
				$isConform = false;
				if ($oneFailImmediatelyReturn) {
					return false;
				}
			}
		}
		return $isConform;
	}

	/**
	 * 缺货数量检查
	 * @param  [type] $waitingGoods [description]
	 * @return [type]               [description]
	 */
	private function _stockoutQuantityCheck($waitingGoods) {
		$checkResult = true;
		$stockoutQuantity = $waitingGoods['quantity'];
		if ($stockoutQuantity <= 0) {
			$checkResult = false;
		}

		return $checkResult;
	}

	/**
	 * 检查产品等级是否符合缺货需求要求
	 * @return [type] [description]
	 */
	private function _productGradeCheck(array $waitingGoods) {
		$checkResult = true;
		$productGradeId = 0;
		if ($waitingGoods['product_grade']) {
			$productGradeId = $waitingGoods['product_grade'];
		}

		if ($productGradeId && $this->isForbidProductGrade($productGradeId)) {
			$checkResult = false;
		}

		$this->_storyBackupLogModel->log('product_grade', $productGradeId);
		return $checkResult;
	}

	/**
	 * 检查产品分类是否符合缺货需求要求
	 * @param  array  $stockOutGoodsog [description]
	 * @return [type]                  [description]
	 */
	private function _productCatalogCheck(array $waitingGoods) {
		$checkResult = true;
		if ($this->isForbidProductCatalog($waitingGoods['catalog_id'])) {
			$checkResult = false;
		}

		$this->_storyBackupLogModel->log('product_catalog', $waitingGoods['catalog_id']);
		return $checkResult;
	}

	/**
	 * 检查产品货源状态是否符合缺货需求要求
	 * @param  array  $stockOutGoods [description]
	 * @return [type]                [description]
	 */
	private function _productResourceStatusCheck(array $waitingGoods) {
		$checkResult = true;
		$resourceStatus = $waitingGoods['resource_status'];
		if ($this->isForbidProductResourceStatus($resourceStatus)) {
			$checkResult = false;
		}
		$this->_storyBackupLogModel->log('resource_status', $resourceStatus);
		return $checkResult;
	}

	/**
	 * 检查产品清仓状态是否符合缺货需求要求
	 * @param  array  $stockOutGoods [description]
	 * @return [type]                [description]
	 */
	private function _productIsClearanceCheck(array $waitingGoods) {
		$checkResult = true;
		if (isset($waitingGoods['is_clearance']) && $waitingGoods['is_clearance']) {
			$checkResult = false;
		}
		$this->_storyBackupLogModel->log('is_clearance', (int) (!$checkResult));
		return $checkResult;
	}

	/**
	 * 生成的缺货需求是否要被拦截(即生成一条缺货需求日志，不产生实际采购需求)
	 * @param  [type] $waitingGoods [description]
	 * @return bool true是不拦截，false是拦截
	 */
	private function _interceptCheck($waitingGoods) {
		$this->_storyModel || $this->_storyModel = new Cron_Model_Backup_Story();
		$salesWarehouse = $waitingGoods['sales_warehouse'];
		$backupWarehouse = $waitingGoods['backup_warehouse'];

		$checkResult = $this->_storyModel->interceptCheck($salesWarehouse, $backupWarehouse);

		$this->_storyBackupLogModel->log('a_story_is_intercept', (int) !$checkResult);
		return $checkResult;
	}

	/**
	 * 获取缺货备货的候选商品列表
	 * @param  [type] $offset [description]
	 * @param  [type] $length [description]
	 * @return [type]         [description]
	 */
	private function _getWaitingGoodsList($offset, $length) {
		return $this->db->query("select stockout.goods_sn,stockout.quantity,stockout.warehouse as backup_warehouse,stockout.stock,stockout.order_occupy_quarter
		 ,product.id,product.wh_code as sales_warehouse,product.catalog_id,
		 warehouse_product.is_clearance as is_clearance,warehouse_product.product_grade,
		 product_purchase.goods_resource_status as resource_status
		 from b_product_stockout as stockout
		 left join p_product as product on stockout.goods_sn=product.goods_sn
		 left join p_product_purchase as product_purchase on stockout.goods_sn=product_purchase.goods_sn
		 left join p_warehouse_product as warehouse_product on stockout.goods_sn=warehouse_product.goods_sn and stockout.warehouse=warehouse_product.warehouse
		 where product.id IS NOT NULL order by stockout.id limit $offset,$length")->fetchAll();
	}
}